package com.stooscloud.provider.impl;

import com.stooscloud.*;
import com.stooscloud.base.enums.ErrorCodeEnum;
import com.stooscloud.base.exception.BusinessException;
import com.stooscloud.core.redis.IdGeneratorUtil;
import com.stooscloud.provider.builder.Builder;
import com.stooscloud.provider.config.TransInitRunner;
import com.stooscloud.provider.impl.doman.CopyTwoThreeElement;
import com.stooscloud.provider.impl.doman.TwoThreeElement;
import com.stooscloud.provider.impl.factory.TwoThreeElementBuilderFactory;
import com.stooscloud.provider.model.dto.TwoThreeElementDto;
import com.stooscloud.provider.model.dto.response.TwoThreeElementRespose;
import com.stooscloud.provider.service.HttpUtils;
import com.stooscloud.provider.service.TwoThreeElementFeignApi;
import com.stooscloud.rsa.RsaCodingUtil;
import com.stooscloud.wrapper.WrapMapper;
import com.stooscloud.wrapper.Wrapper;
import config.properties.WsProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static org.springframework.util.ResourceUtils.getFile;
@Component
@Slf4j
public class TwoThreeElementBuilder implements Builder<TwoThreeElement> {

    @Autowired
    private TransInitRunner transInitRunner;
    @Autowired
    private TwoThreeElementBuilderFactory twoThreeElementBuilderFactory;
    @Resource
    private TwoThreeElementFeignApi twoThreeElementFeignApi;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    WsProperties wsProperties;

    private TwoThreeElement twoThreeElement;
    private TwoThreeElementDto twoThreeElementDto;
    private TwoThreeElementRespose twoThreeElementRespose;
    @Override
    public TwoThreeElement createDoman(Object obj) {
        try {
            this.twoThreeElement = twoThreeElementBuilderFactory.builderObj(obj);
            log.info("接收前端的报文信息:{}",this.twoThreeElement.toString());
        }catch (Exception ex){
            if(ex instanceof BusinessException){
                throw ex;
            }else {
                throw new BusinessException(1002,"解析上传报文失败!");
            }
        }
        return null;
    }

    @Override
    public void handler() {
        twoThreeElementDto = new TwoThreeElementDto();
        CopyTwoThreeElement copyTwoThreeElement = new CopyTwoThreeElement();
        BeanUtils.copyProperties(twoThreeElement,copyTwoThreeElement);
        String jsonData = "";
        try {
            jsonData = JacksonUtil.toJson(copyTwoThreeElement);
        } catch (IOException e) {
            log.error("实体类转换json字符串失败,【errMsg】:{}",e.getMessage());
            throw new BusinessException(1003,"实体类转换json字符串失败",e);
        }
        String data_content = RsaDate(jsonData);
        log.info("====加密串:" + data_content);
        twoThreeElementDto.setMember_id(twoThreeElement.getMember_id());
        twoThreeElementDto.setTerminal_id(twoThreeElement.getTerminal_id());
        twoThreeElementDto.setData_content(data_content);
        twoThreeElementDto.setData_type("json");
    }

    @Override
    public void idBus() {
        if (transInitRunner.busMap.get(twoThreeElement.getSystemId()+"_"+twoThreeElement.getTranCode())){
            log.info("开始业务逻辑处理");
        }
    }

    @Override
    public void call() {
        try {
            Map<String, Object> params = BeanToMapUtil.beanToMap(twoThreeElementDto);
            twoThreeElementRespose = twoThreeElementFeignApi.call(params);
        } catch (Exception e) {
            log.error("请求服务端失败",e);
            if (twoThreeElementRespose == null)
                twoThreeElementRespose = new TwoThreeElementRespose();
            twoThreeElementRespose.setErrorCode("S0001");
            twoThreeElementRespose.setErrorMsg("系统繁忙，请稍后再试");
        }

    }

    @Override
    public Wrapper installWrapper() {
        if (StringUtils.isBlank(twoThreeElementRespose.getErrorCode())|| StringUtils.isBlank(twoThreeElementRespose.getErrorMsg())){
            twoThreeElementRespose.setErrorCode("0000");
            twoThreeElementRespose.setErrorMsg("交易成功");
            if (twoThreeElementRespose.getData() != null)
                updateRedisMsg();
        }
        return WrapMapper.wrap(twoThreeElementRespose.getErrorCode(),twoThreeElementRespose.getErrorMsg(),twoThreeElementRespose.getData());
    }

    private String RsaDate(String jsonData){
        /** base64 编码 **/
        String base64str = Base64Util.encoder(jsonData, Charset.forName("UTF-8"));
        log.info("请求报文base64编码:{}",base64str);
        String pfxpath = getPfxPath();
        log.info("私钥文件路径:{}",pfxpath);
        if (pfxpath == null){
            log.error("获取私钥文件失败");
            throw new BusinessException(1004,"获取私钥文件失败");
        }
        return RsaCodingUtil.encryptByPriPfxFile(base64str, pfxpath, wsProperties.getPfx().getPwd());// 加密数据
    }

    private String getPfxPath(){
        File file = null;
        try {
            file = getFile("classpath:key/8150708133_pri.pfx");
        } catch (FileNotFoundException e) {
            log.error("无法获取私钥文件,返回私钥文件配置信息路径!");
            return wsProperties.getPfx().getPfxPath();
        }
        if (file != null){
            return file.getPath();
        }else {
            return null;
        }
    }

    private void updateRedisMsg(){
        redisTemplate.opsForValue().set(RedisKeyUtil.getTwoThreeElement(twoThreeElementRespose.getData().getCode(),twoThreeElement.getTrans_id()),twoThreeElementDto.getData_content());
    }

}
